package org.pih.javarosa.applogic;

import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;

import javax.microedition.midlet.MIDlet;

import org.javarosa.core.model.CoreModelModule;
import org.javarosa.core.model.FormDef;
import org.javarosa.core.model.condition.IFunctionHandler;
import org.javarosa.core.model.utils.IPreloadHandler;
import org.javarosa.core.reference.ReferenceManager;
import org.javarosa.core.reference.RootTranslator;
import org.javarosa.core.services.PropertyManager;
import org.javarosa.core.services.locale.Localization;
import org.javarosa.core.services.properties.JavaRosaPropertyRules;
import org.javarosa.core.services.storage.IStorageIterator;
import org.javarosa.core.services.storage.IStorageUtility;
import org.javarosa.core.services.storage.StorageFullException;
import org.javarosa.core.services.storage.StorageManager;
import org.javarosa.core.services.transport.payload.IDataPayload;
import org.javarosa.core.util.JavaRosaCoreModule;
import org.javarosa.core.util.PropertyUtils;
import org.javarosa.formmanager.FormManagerModule;
import org.javarosa.j2me.J2MEModule;
import org.javarosa.j2me.util.DumpRMS;
import org.javarosa.j2me.view.J2MEDisplay;
import org.javarosa.model.xform.XFormsModule;
import org.javarosa.patient.PatientModule;
import org.javarosa.patient.model.Patient;
import org.javarosa.resources.locale.LanguagePackModule;
import org.javarosa.resources.locale.LanguageUtils;
import org.javarosa.services.transport.TransportManagerModule;
import org.javarosa.services.transport.TransportMessage;
import org.javarosa.services.transport.impl.simplehttp.SimpleHttpTransportMessage;
import org.javarosa.user.activity.UserModule;
import org.javarosa.user.model.User;
import org.javarosa.user.utility.UserUtility;
import org.javarosa.xform.util.XFormUtils;
import org.pih.javarosa.model.Drug;
import org.pih.javarosa.module.DrugModule;
import org.pih.javarosa.properties.AdultDosageAppProperties;
import org.pih.javarosa.util.AdultDosageUtil;
import org.pih.javarosa.util.MetaPreloadHandler;

//#if app.uselocation && polish.api.locationapi
//import org.javarosa.location.LocationModule;
//#endif

public class AdultDosageContext {

	private static AdultDosageContext instance;

	public static AdultDosageContext _ () {
		if (instance == null) {
			instance = new AdultDosageContext();
		}
		return instance;
	}

	private MIDlet midlet;
	private User user;
	private int patientID;
	private int drugId;
	private int countryId;

	private IStorageUtility forms;

	public void setMidlet(MIDlet m) {
		this.midlet = m;
		J2MEDisplay.init(m);
	}

	public MIDlet getMidlet() {
		return midlet;
	}

	public void init (MIDlet m) {
		DumpRMS.RMSRecoveryHook(m);

		setMidlet(m);
		loadModules();

		System.out.println(this.getClass().getName() + ".init: 1");		

		setForms(StorageManager.getStorage(FormDef.STORAGE_KEY));
		//		if (getForms().getNumRecords() == 0) {
		//System.out.println(this.getClass().getName() + ".init: calling loadForms");		
		//			loadForms(getForms());
		//System.out.println(this.getClass().getName() + ".init: completed loadForms");		
		//		}
		addCustomLanguages();
		setProperties();

		//		IStorageUtility patients = StorageManager.getStorage(Patient.STORAGE_KEY);
		//		if (patients.getNumRecords() == 0) {
		//			AdultDosageUtil.loadDemoPatients(patients);
		//		}

		System.out.println(this.getClass().getName() + ".init: 2");		


//		IStorageUtility drugs = StorageManager.getStorage(Drug.STORAGE_KEY);
//		System.out.println(this.getClass().getName() + ".init: drugs.getNumRecords(): " + drugs.getNumRecords());		
//		if (drugs.getNumRecords() == 0) {
//			System.out.println(this.getClass().getName() + ".init: calling loadDrugs");		
//			AdultDosageUtil.loadDrugs(drugs);
//			System.out.println(this.getClass().getName() + ".init: completed loadDrugs");		
//		}

		UserUtility.populateAdminUser();
		loadRootTranslator();
	}

	public void loadForm(String formName, String protocolXFormPath) {
		try {
			if (getFormId(formName) == null) {
				forms.write(XFormUtils.getFormFromResource("/" + protocolXFormPath));
				System.out.println(this.getClass().getName() + ".loadForm: Loading " + protocolXFormPath);
//				forms.write(XFormUtils.getFormFromResource("/Acetaminophen.xml"));
			}
		} catch (NullPointerException e) {
			throw new RuntimeException("Null Pointer Exception"); //TODO: handle this
		} catch (StorageFullException e) {
			throw new RuntimeException("uh-oh, storage full [forms]"); //TODO: handle this
		}
	}

	public Integer getFormId (String formName) {
		IStorageIterator formList = forms.iterate();
		while (formList.hasMore()) {
			FormDef form = (FormDef) formList.nextRecord();
			
			System.out.println(this.getClass().getName() + ".getFormId: Comparing " + formName + " with " + form.getName() + "::" + form.getLabelInnerText() + "::" + form.getTextID());
			
			if (form.getTitle().equalsIgnoreCase(formName)) {
				
				return new Integer(form.getID());
			}
		}
		return null;
	}
	
	
	//	private void loadForms (IStorageUtility forms) {
	//		try {
	//			forms.write(XFormUtils.getFormFromResource("/Acetaminophen.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Aciclovir.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/AcetylsalicylicAcid.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/FolicAcid.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Albendazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/AlbuterolNebulizer.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/AlbuterolSpray.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Allopurinol.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Ambroxol.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/AmbroxolDextromethorphan.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Amoxicillin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/AmoxicillinwithClavulanicAcid.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Ampicillin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Azithromycin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Bacitracin-Neomycin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/BenzylBenzoate.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Benzonatate.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Betamthasonevalerato.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/SodiumBicarbonate.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/SunBlock.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Bromohexine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Butylhyoscine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/CalciumCarbonate.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Calamine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/KaolinPection.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Captopril.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Carbamazepine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Cefadroxil.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/CeftriaxoneLidocaine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/CiprofloxacinTablets.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/CiprofloxacinEyedrops.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Clindamycin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Lysineclonixinate.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/LysineclonixinateandPropinox.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Chloramphenicoldrops.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Chloramphenicoltablets.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Clorphenamine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/ClotrimazoledermalCream.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Clotrimazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/ComplejoB.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/DiclofenacGel.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Enalapril.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Erythromycin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Espradentablets.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Exalver.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/FenitoinaSodica.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Furosemide.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Fluconazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/FluocinolonaClioquinol.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Fluoxetine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/FumeratoFerroso.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/FerrosoSulfato.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Gentamicin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Glyburide-Glibenclamida.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/GuayacolatodeGlicerilo.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Hydrocortisone.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Ibuprofen.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Itraconazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Ketoconazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Lansoprazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Levofloxacin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Loratadinetablets.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Loratadinejarabe.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/MeclizinaPiridoxina.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Mebendazoletablets.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Metformin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Methocarbamol.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Metoclopramide.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Metropolol.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Metronidazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/MetronidazoleVaginaltabletsovules.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Miconazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Mupirocin.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Nafazolina-HipromelosaOftal.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Pantoprazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Ranitidine.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Salbutamol.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Bismuthsubsalicylate.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Tetracycline.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Tinidazole.xml"));
	//			forms.write(XFormUtils.getFormFromResource("/Trimetoprim-Sulfametoxazol.xml"));
	//		} catch (StorageFullException e) {
	//			throw new RuntimeException("uh-oh, storage full [forms]"); //TODO: handle this
	//		}
	//	}

	private void loadModules() {
		new J2MEModule().registerModule();
		new JavaRosaCoreModule().registerModule();
		new CoreModelModule().registerModule();
		new XFormsModule().registerModule();
		new LanguagePackModule().registerModule();
		new TransportManagerModule().registerModule();
		new UserModule().registerModule();
		//		new PatientModule().registerModule();
		new DrugModule().registerModule();
		new FormManagerModule().registerModule();
		new LanguagePackModule().registerModule();

		//#if app.uselocation && polish.api.locationapi
		//		new LocationModule().registerModule();
		//#endif
	}


	private void addCustomLanguages() {
		Localization.registerLanguageFile("Afrikaans", "./messages_afr.txt");
		Localization.registerLanguageFile("Dari", "./messages_dari.txt");
		Localization.registerLanguageFile("Espagnol", "./messages_es.txt");
		Localization.registerLanguageFile("Swahili", "./messages_sw.txt");
		Localization.registerLanguageFile("English", "./messages_en.txt");		
	}

	private void setProperties() {
		final String POST_URL = "http://staging.commcarehq.org/receiver/submit/test";

		PropertyManager._().addRules(new JavaRosaPropertyRules());
		PropertyManager._().addRules(new AdultDosageAppProperties());
		PropertyUtils.initializeProperty("DeviceID", PropertyUtils.genGUID(25));

		PropertyUtils.initializeProperty(AdultDosageAppProperties.POST_URL_LIST_PROPERTY, POST_URL);
		PropertyUtils.initializeProperty(AdultDosageAppProperties.POST_URL_PROPERTY, POST_URL);

		LanguageUtils.initializeLanguage(true, "en");
	}

	public void setUser (User u) {
		this.user = u;
	}

	public User getUser () {
		return user;
	}

	public void setPatientID (int patID) {
		this.patientID = patID;
	}

	public int getPatientID () {
		return this.patientID;
	}

	public void setDrugId (int drugId) {
		this.drugId = drugId;
	}

	public int getDrugId () {
		return this.drugId;
	}

	public TransportMessage buildMessage(IDataPayload payload) {
		//Right now we have to just give the message the stream, rather than the payload,
		//since the transport layer won't take payloads. This should be fixed _as soon 
		//as possible_ so that we don't either (A) blow up the memory or (B) lose the ability
		//to send payloads > than the phones' heap.
		try {
			return new SimpleHttpTransportMessage(payload.getPayloadStream(), PropertyManager._().getSingularProperty(AdultDosageAppProperties.POST_URL_PROPERTY));
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("Error Serializing Data to be transported");
		}
	}

	public Vector<IPreloadHandler> getPreloaders() {
		Vector<IPreloadHandler> handlers = new Vector<IPreloadHandler>();
		MetaPreloadHandler meta = new MetaPreloadHandler(this.getUser());
		handlers.addElement(meta);
		return handlers;		
	}

	public Vector<IFunctionHandler> getFuncHandlers () {
		return null;
	}

	public void loadRootTranslator(){
		ReferenceManager._().addRootTranslator(new RootTranslator("jr://images/", "jr://resource/"));
		ReferenceManager._().addRootTranslator(new RootTranslator("jr://audio/", "jr://resource/"));
	}

	public void setCountryId(int countryId) {
		System.out.println(this.getClass().getName() + ".setCountryId: Setting country id to: " + countryId);
		this.countryId = countryId;
	}

	public int getCountryId() {
		return countryId;
	}

	public void setForms(IStorageUtility forms) {
		this.forms = forms;
	}

	public IStorageUtility getForms() {
		return forms;
	}
}
